package com.yangjun.service.report;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.yangjun.common.ServerResponse;
import com.yangjun.common.comparator.TargetItemComparator;
import com.yangjun.common.comparator.TargetItemComparatorByTargetArr;
import com.yangjun.common.enums.SummaryCycleEnum;
import com.yangjun.common.excel.DataBaseExcelContext;
import com.yangjun.common.excel.ExcelExportResult;
import com.yangjun.dao.mybatis.mapper.report.DvReportSearchTmpMapper;
import com.yangjun.dao.mybatis.mapper.report.ReportDownloadStatusMapper;
import com.yangjun.dao.mybatis.mapper.report.ReportExportStatusMapper;
import com.yangjun.dao.mybatis.mapper.report.ReportImportStatusMapper;
import com.yangjun.dao.mybatis.mapper.report.SingleProductReportExportMapper;
import com.yangjun.dao.mybatis2.mapper.common.CommonMapper;
import com.yangjun.entity.report.DvExcelFieldDefinitionEntity;
import com.yangjun.entity.report.DvReportDownloadStatusEntity;
import com.yangjun.entity.report.DvReportExportStatus;
import com.yangjun.entity.report.DwSingleProductEntity;
import com.yangjun.po.report.SingleProductReportExportPO;
import com.yangjun.service.common.CommonService;
import com.yangjun.service.permission.ReportExportPermissionService;
import com.yangjun.utils.DvDateUtils;
import com.yangjun.utils.DvUtils;
import com.yangjun.utils.POIExcelUtils;
import com.yangjun.vo.report.SingleProductReportExportVO;
import com.yangjun.vo.report.SingleProductReportManageVO;
@Service
public class SingleProductReprotExportService  {
	@Value("${excel.uploadPath}")
    private String uploadPath;
	@Value("${excel.downloadPath}")
    private String downloadPath;
	
	@Autowired
	private DataBaseExcelContext context;
	private final static String reporttype = "singleProduct";
	@Autowired
	private SingleProductReportExportMapper singleProductReportExportMapper;
	@Autowired
	private ReportExportStatusMapper reportExportStatusMapper;
	@Autowired
	private ReportImportStatusMapper reportImportStatusMapper;
	@Autowired
	private ReportDownloadStatusMapper reportDownloadStatusMapper;
	@Autowired
	private DvReportSearchTmpMapper dvReportSearchTmpMapper;
	@Autowired
	private CommonService commonService;
	@Autowired
	private ReportCommonService reportCommonService;
	@Autowired
	private ReportExportPermissionService reportExportPermissionService;
 	@Autowired
 	private CommonMapper commonMapper;
	


	/**
	 * @Description 获取维度信息
	 * @return
	 * @author yangjun
	 * @Date 2017年7月5日 上午11:50:06
	 */
	//fetchType(取数类型) : 临时(temporary)订阅(subscription)
	//summaryCycle(汇总周期) : naturalDay(自然天)naturalWeek(自然周)naturalMonth(自然月)custom(自定义)
	public Object getDeminsion(String reportid,String userid){
		SingleProductReportExportVO spreVo = null;
		DvReportExportStatus dvReportExportStatus = reportExportStatusMapper.queryReportStatusByReportId(reportid);
		
		String[] targetSelectData  = null;
		//修改报表排序号的字段顺序
		List<Map<String,Object>> sortTargetSelectData=Lists.newArrayList();
		String reportName = "单品分析-";
		String uploadFileId = "";
		String uploadFileName = "";
		String searchName = "wareCode";
		String searchValue = "";
		//平台
		String[] saveOrdersourceArr = null;
		int type = reportExportPermissionService.getManagerType(userid, reporttype);
		
		List<Map<String, Object>> ordersource = commonService.getOrderSource(type,userid,reporttype);
		//取数类型(默认临时取数)
		String fetchType = "temporary";
		//汇总周期(默认自然天)
		String summaryCycle = "naturalDay";
		//查询开始时间(默认都是昨天)
		String beginDate = DvDateUtils.getDate(new Date(), -1);
		//查询结束时间(默认都是昨天)
		String endDate = DvDateUtils.getDate(new Date(), -1);
		Boolean modify = dvReportExportStatus!=null?true:false;
		
		if(dvReportExportStatus!=null){
			spreVo = JSON.parseObject(dvReportExportStatus.getReportparam(), SingleProductReportExportVO.class);
			targetSelectData = spreVo.getTarget();
			reportName = spreVo.getReportName();
			uploadFileId = spreVo.getUploadFileId();
			if(StringUtils.isNotBlank(uploadFileId)){
				uploadFileName = reportImportStatusMapper.queryReportStatusByUUID(uploadFileId).getReportName();
			}
			saveOrdersourceArr = spreVo.getOrdersource();
			fetchType = spreVo.getFetchType();
			summaryCycle = spreVo.getSummaryCycle();
			beginDate = spreVo.getBeginDate();
			endDate = spreVo.getEndDate();
			
			searchName = spreVo.getSearchName();
			searchValue = spreVo.getSearchValue().length>0?spreVo.getSearchValue()[0]:"";
		}
		Map<String,Object> demensionMap = Maps.newHashMap();
		//平台
		for(Map<String, Object> ordersourceItem : ordersource){
			if(saveOrdersourceArr!=null){
				ordersourceItem.put("checked", false);
				String[] os = ordersourceItem.get("ordersource").toString().split(",");
				for(String osItem : os){
					if(ArrayUtils.contains(saveOrdersourceArr, osItem)){
						ordersourceItem.put("checked", true);
					}
				}
			}else{
				ordersourceItem.put("checked", true);
			}
		}
		demensionMap.put("ordersource",ordersource);
		//取数类型
		demensionMap.put("fetchType",fetchType);
		//汇总周期
		demensionMap.put("summaryCycle",summaryCycle);
		//查询日期
		demensionMap.put("dateMethod", queryDateMethod(modify,summaryCycle,beginDate,endDate));
		//开始时间
		demensionMap.put("beginDate", beginDate);
		//结束时间
		demensionMap.put("endDate", endDate);

		demensionMap.put("reportName",reportName);
		demensionMap.put("uploadFileName", uploadFileName);
		demensionMap.put("uploadFileId", uploadFileId);
		List<DvExcelFieldDefinitionEntity> excelFieldDefinitionList = reportCommonService.getExcelFieldDefinitionList(reporttype);
		
		
		//获取每个报表的指标分类
		Map<String,String> tmpCategoryMap = reportCommonService.queryCategory(reporttype);
		List<Map<String,String>> categoryList = Lists.newArrayList();
		
		Map<String,List<Map<String,Object>>> targetMap = Maps.newHashMap();
		List<Map<String,Object>> targetList =null;
		for(Map.Entry<String,String> categoryEntry: tmpCategoryMap.entrySet()){
			//初始化指标分类数组
			Map<String,String> categoryMap = Maps.newHashMap();
			categoryMap.put("name", categoryEntry.getKey());
			categoryMap.put("value", categoryEntry.getValue());
			categoryList.add(categoryMap);
			//初始化指标分类内容
			targetList = Lists.newArrayList();
			targetMap.put(categoryEntry.getKey(),targetList);
		}
		demensionMap.put("category", categoryList);
		
		
		//查询有权限显示的报表字段
		String[] allowFieldArr = reportExportPermissionService.getReportAllowField(userid, reporttype);
		if(allowFieldArr!=null&&allowFieldArr.length>0){
			for(DvExcelFieldDefinitionEntity excelFieldDefinitionEntity : excelFieldDefinitionList){
				//权限控制能够显示的字段，如果查询不到对应角色的权限直接不显示字段。
				//&&("18".equals(userid)||"507".equals(userid)||"715".equals(userid)||"6".equals(userid)||"518".equals(userid)||"141".equals(userid)||"481".equals(userid))
				if(allowFieldArr!=null){
					List<String> allowFieldList = Arrays.asList(allowFieldArr);
					if(!allowFieldList.contains(excelFieldDefinitionEntity.getEntityName())){
						continue;
					}
				}
				//封装默认的指标格式
				String categoryId = excelFieldDefinitionEntity.getCategoryId();
				if(StringUtils.isNotBlank(categoryId)){
					String entityName = excelFieldDefinitionEntity.getEntityName();
					String title = excelFieldDefinitionEntity.getTitle();
					int sort = excelFieldDefinitionEntity.getFieldSort();
					Map<String,Object> itemMap = Maps.newHashMap();
					itemMap.put("value", entityName);
					itemMap.put("name", title);
					itemMap.put("sort", sort);
					itemMap.put("checked", false);
					if(targetSelectData!=null){
						for(int i=0,len=targetSelectData.length;i<len;i++){
							if(entityName.equals(targetSelectData[i])){
								itemMap.put("checked", true);
								//修改报表排序号的字段顺序
								sortTargetSelectData.add(itemMap);
							}
						}					
					}else{
						if("sourcename".equals(entityName)){
							//单品分析平台指标默认是true
							itemMap.put("checked", true);
						}
					}

					targetList = targetMap.get(categoryId);
					//已经在上面初始化了不用判断空
					targetList.add(itemMap);
				}
			}
			//根据数据库给定的sort字段进行排序
			for(Map.Entry<String,List<Map<String,Object>>> targetItemEntry : targetMap.entrySet()){
					Collections.sort(targetItemEntry.getValue(),new TargetItemComparator());
			}
		}
		
		filterCustomTarget(targetMap);
		demensionMap.put("reporttype", reporttype);
		demensionMap.put("target", targetMap);
		
		String[] searchWayNameArr = {"商品编码","商品名称"};
		String[] searchWayValueArr = {"wareCode","wareName"};
		List<Map<String,String>> searchWayList = Lists.newArrayList();
		for(int i = 0,len=searchWayNameArr.length;i<len;i++){
			Map<String,String> searchMap = Maps.newHashMap();
			searchMap.put("searchWayName", searchWayNameArr[i]);
			searchMap.put("searchWayValue", searchWayValueArr[i]);
			searchWayList.add(searchMap);
		}

		demensionMap.put("search", searchWayList);
		demensionMap.put("searchName", searchName);
		demensionMap.put("searchValue", searchValue);
		Collections.sort(sortTargetSelectData, new TargetItemComparatorByTargetArr(targetSelectData));
		demensionMap.put("sortTarget", sortTargetSelectData);
		reportCommonService.deleteUploadReport(userid);
		return ServerResponse.createBySuccess(demensionMap);
	}
	
	private Map<String,List<Map<String,Object>>> filterCustomTarget(Map<String,List<Map<String,Object>>> map){
		List<Map<String,Object>> customFilterList = new ArrayList<Map<String,Object>>();
		String[] customFilter = new String[]{"newPurchaseNum","newPurorderNum","newPurchaseAmt"};
		List<Map<String,Object>> targetList = map.get("memberAnalysis");
		for(Map<String,Object> targetMap : targetList){
			String value = targetMap.get("value").toString();
			for(String filterItem : customFilter){
				if(value.equals(filterItem)){
					customFilterList.add(targetMap);
				}
			}
		}
		map.put("customFilter", customFilterList);
		return map;
	}
	
	private Object queryDateMethod(Boolean modify,String summaryCycle,String beginDate,String endDate){
		//summaryCycle(汇总周期) : naturalDay(自然天)naturalWeek(自然周)naturalMonth(自然月)custom(自定义)
		Map<String,Map<String,Object>> resultMap = Maps.newHashMap();
		String[] fetchTypeArr = {"temporary","subscription"};
		for(String fetchTypeItem : fetchTypeArr ){
			if("temporary".equals(fetchTypeItem)){
				//临时取数
				resultMap.put(fetchTypeItem, queryDateOfTemporaryWay(summaryCycle,beginDate,endDate));
			}else if("subscription".equals(fetchTypeItem)){
				//订阅报表
				resultMap.put(fetchTypeItem, queryDateOfSubscriptionWay(modify,summaryCycle,beginDate,endDate));
			}
		}
		return resultMap;
	}
	private Map<String,Object> queryDateOfSubscriptionWay(Boolean modify,String summaryCycle,String beginDate,String endDate){
		Map<String,Object> resultMap = Maps.newHashMap();
		String[] summaryCycleArr = {"naturalDay","naturalWeek","naturalMonth","custom"};
		for(String summaryCycleItem : summaryCycleArr){
			if("naturalDay".equals(summaryCycleItem)){
				//自然天，过去7天，默认第一个选中
				List<Map<String,String>> naturalDayList = Lists.newArrayList();
				String edOfNaturalDay = DvDateUtils.getDate(new Date(), -1);
				for(int i=1;i<=7;i++){
					Map<String,String> naturalDayMap = Maps.newHashMap();
					String selected = "false";
					
					String bdOfNaturalDay = DvDateUtils.getDate(new Date(), -i);
					naturalDayMap.put("name","过去"+i+"天");
					naturalDayMap.put("beginDate",bdOfNaturalDay);
					naturalDayMap.put("endDate",edOfNaturalDay);
					if(modify){
						if(summaryCycleItem.equals(summaryCycle)&&bdOfNaturalDay.equals(beginDate)&&edOfNaturalDay.equals(endDate)){
							selected = "true";
						}
					}else{
						if(i==1){
							selected = "true";
						}
					}
					naturalDayMap.put("selected",selected);
					naturalDayList.add(naturalDayMap);
				}
				resultMap.put(summaryCycleItem, naturalDayList);
			}else if("naturalWeek".equals(summaryCycleItem)){
				List<Map<String,String>> naturalWeekList = Lists.newArrayList();
				String edOfNaturalWeek = DvDateUtils.format(DvDateUtils.getOffsetDay(DvDateUtils.getLastDayOfWeek(new Date()),-7),"yyyy-MM-dd");
				for(int i=1;i<=7;i++){
					Map<String,String> naturalWeekMap = Maps.newHashMap();
					String selected = "false";
					String bdOfNaturalWeek = DvDateUtils.format(DvDateUtils.getOffsetDay(DvDateUtils.getFirstDayOfWeek(new Date()),-7*i),"yyyy-MM-dd");
					naturalWeekMap.put("name","过去"+i+"周");
					naturalWeekMap.put("beginDate",bdOfNaturalWeek);
					naturalWeekMap.put("endDate",edOfNaturalWeek);
					if(modify){
						if(summaryCycleItem.equals(summaryCycle)&&bdOfNaturalWeek.equals(beginDate)&&edOfNaturalWeek.equals(endDate)){
							selected = "true";
						}
					}else{
						if(i==1){
							selected = "true";
						}
					}
					naturalWeekMap.put("selected",selected);
					naturalWeekList.add(naturalWeekMap);
				}
				resultMap.put(summaryCycleItem, naturalWeekList);
			}else if("naturalMonth".equals(summaryCycleItem)){
				List<Map<String,String>> naturalMonthList = Lists.newArrayList();
				int year = DvDateUtils.getYear(new Date());
				int month = DvDateUtils.getMonth(new Date())-1;
				String edDateOfMonth = DvDateUtils.format(DvDateUtils.getLastDayOfMonth(year, month),"yyyy-MM-dd");
				for(int i=1;i<=3;i++){
					Map<String,String> naturalMonthMap = Maps.newHashMap();
					String selected = "false";
					month = DvDateUtils.getMonth(new Date())-i;
					String bdDateOfMonth = DvDateUtils.format(DvDateUtils.getFirstDayOfMonth(year, month),"yyyy-MM-dd");
					naturalMonthMap.put("name","过去"+i+"个月");
					naturalMonthMap.put("beginDate",bdDateOfMonth);
					naturalMonthMap.put("endDate",edDateOfMonth);
					if(modify){
						if(summaryCycleItem.equals(summaryCycle)&&bdDateOfMonth.equals(beginDate)&&edDateOfMonth.equals(endDate)){
							selected = "true";
						}
					}else{
						if(i==1){
							selected = "true";
						}
					}
					naturalMonthMap.put("selected",selected);
					naturalMonthList.add(naturalMonthMap);
				}
				resultMap.put(summaryCycleItem, naturalMonthList);
			}else if("custom".equals(summaryCycleItem)){
				List<Map<String,String>> customList = Lists.newArrayList();
				String[] customDateArr = new String[]{"7","15","30","60"};
				String edOfCustomDay = DvDateUtils.getDate(new Date(), -1);
				for(int i=0,len=customDateArr.length;i<len;i++){
					Map<String,String> customMap = Maps.newHashMap();
					String selected = "false";
					String bdOfCustomDay = DvDateUtils.getDate(new Date(), -Integer.valueOf(customDateArr[i]));
					customMap.put("name","过去"+customDateArr[i]+"天");
					customMap.put("beginDate",bdOfCustomDay);
					customMap.put("endDate",edOfCustomDay);
					if(modify){
						if(summaryCycleItem.equals(summaryCycle)&&bdOfCustomDay.equals(beginDate)&&edOfCustomDay.equals(endDate)){
							selected = "true";
						}
					}else{
						if(i==0){
							selected = "true";
						}
					}
					customMap.put("selected",selected);
					customList.add(customMap);
				}
				resultMap.put(summaryCycleItem, customList);
			}
		}
		return resultMap;

	}
	private Map<String,Object> queryDateOfTemporaryWay(String summaryCycle,String beginDate,String endDate){
		Map<String,Object> resultMap = Maps.newHashMap();
		String[] summaryCycleArr = {"naturalDay","naturalWeek","naturalMonth","custom"};
		for(String summaryCycleItem : summaryCycleArr){
			Map<String,Object> itemMap = Maps.newHashMap();
			if("naturalDay".equals(summaryCycleItem)){
				itemMap.put("beginDate", DvDateUtils.getDate(new Date(), -90));
				itemMap.put("endDate", DvDateUtils.getDate(new Date(), -1));
			}else if("naturalWeek".equals(summaryCycleItem)){
				List<Map<String,String>> naturalWeekBeginList = Lists.newArrayList();
				List<Map<String,String>> naturalWeekEndList = Lists.newArrayList();

				for(int i=1;i<=7;i++){
					Map<String,String> naturalWeekBeginMap = Maps.newHashMap();
					Map<String,String> naturalWeekEndMap = Maps.newHashMap();
					String bdSelected = "false";
					String edSselected = "false";

					//过去7周的第一天
					String beginDateOfWeek = DvDateUtils.format(DvDateUtils.getOffsetDay(DvDateUtils.getFirstDayOfWeek(new Date()),-i*7),"yyyy-MM-dd");
					//过去7周的最后一天
					String endDateOfWeek = DvDateUtils.format(DvDateUtils.getOffsetDay(DvDateUtils.getLastDayOfWeek(new Date()),-i*7),"yyyy-MM-dd");
					int week = DvDateUtils.getWeekOfYear(DvDateUtils.getOffsetDay(DvDateUtils.getFirstDayOfWeek(new Date()),-i*7));
					int year = DvDateUtils.getYear(DvDateUtils.StrToDate(beginDateOfWeek,"yyyy-MM-dd"));
					naturalWeekBeginMap.put("name", year+"W"+week+"("+beginDateOfWeek+")");
					naturalWeekBeginMap.put("value", beginDateOfWeek);
					
					naturalWeekEndMap.put("name", year+"W"+week+"("+endDateOfWeek+")");
					naturalWeekEndMap.put("value", endDateOfWeek);

					if(i==1){
						bdSelected = "true";
						edSselected = "true";
					}
					naturalWeekBeginMap.put("selected", bdSelected);
					naturalWeekBeginList.add(naturalWeekBeginMap);
					naturalWeekEndMap.put("selected", edSselected);
					naturalWeekEndList.add(naturalWeekEndMap);
					
					itemMap.put("beginDate", naturalWeekBeginList);
					itemMap.put("endDate", naturalWeekEndList);
					
				}
				
			}else if("naturalMonth".equals(summaryCycleItem)){
				List<Map<String,String>> naturalMonthBeginList = Lists.newArrayList();
				List<Map<String,String>> naturalMonthEndList = Lists.newArrayList();
				for(int i=0;i<3;i++){
					Map<String,String> naturalMonthBeginMap = Maps.newHashMap();
					Map<String,String> naturalMonthEndMap = Maps.newHashMap();
					String bdSelected = "false";
					String edSselected = "false";
					int year = DvDateUtils.getYear(new Date());
					int month = DvDateUtils.getMonth(new Date())-i;
					String beginDateOfMonth = DvDateUtils.format(DvDateUtils.getFirstDayOfMonth(year, month-1),"yyyy-MM-dd");
					String endDateOfMonth = DvDateUtils.format(DvDateUtils.getLastDayOfMonth(year, month-1),"yyyy-MM-dd");
					
					year = DvDateUtils.getYear(DvDateUtils.StringToDate(beginDateOfMonth, "yyyy-MM-dd"));
					month = DvDateUtils.getMonth(DvDateUtils.StringToDate(beginDateOfMonth, "yyyy-MM-dd"))+1;
					
					naturalMonthBeginMap.put("name", year+"年"+month+"月");
					naturalMonthBeginMap.put("value", beginDateOfMonth);
					
					naturalMonthEndMap.put("name", year+"年"+month+"月");
					naturalMonthEndMap.put("value", endDateOfMonth);

					if(i==0){
						bdSelected = "true";
						edSselected = "true";
					}
					naturalMonthBeginMap.put("selected", bdSelected);
					naturalMonthBeginList.add(naturalMonthBeginMap);
					naturalMonthEndMap.put("selected", edSselected);
					naturalMonthEndList.add(naturalMonthEndMap);
					
					itemMap.put("beginDate", naturalMonthBeginList);
					itemMap.put("endDate", naturalMonthEndList);
					
				}
			}else if("custom".equals(summaryCycleItem)){
				itemMap.put("beginDate", DvDateUtils.getDate(new Date(), -92));
				itemMap.put("endDate", DvDateUtils.getDate(new Date(), -1));
			}
			resultMap.put(summaryCycleItem, itemMap);
		}
		return resultMap;
	}
	
	private void addGorups(SingleProductReportExportPO sprePo,String groupId){
		if("shopname".equals(groupId)){
			sprePo.setShopname(true);
		}else if("facategory".equals(groupId)){
			sprePo.setFacategory(true);
		}else if("department".equals(groupId)){
			sprePo.setDepartment(true);
		}else if("tmDepartment".equals(groupId)){
			sprePo.setTmDepartment(true);
		}else if("waregeneralname".equals(groupId)){
			sprePo.setWaregeneralname(true);
		}else if("brandname".equals(groupId)){
			sprePo.setBrandname(true);
		}else if("model".equals(groupId)){
			sprePo.setModel(true);
		}else if("sourcename".equals(groupId)){
			sprePo.setSourcename(true);
		}
	}
	private void addCategory(SingleProductReportExportPO sprePo,String categoryId){
		if("memberAnalysis".equals(categoryId)){
			sprePo.setMemberAnalysis(true);
		}else if("flowTransform".equals(categoryId)){
			sprePo.setFlowTransform(true);
		}else if("selfMember".equals(categoryId)){
			sprePo.setSelfMember(true);
		}
	}
	private List<String> getTargetList(String summaryCycle,String[] targetArr){
		List<String> targetList = Lists.newArrayList();
		String[] defaultArr = new String[]{"warecode","warename"};

		if("naturalWeek".equals(summaryCycle)){
			targetList.add("year");
			targetList.add("week");
		}else if("naturalMonth".equals(summaryCycle)){
			targetList.add("year");
			targetList.add("month");
		}else{
			targetList.add("dataDate");
		}
		for(String defaultItem : defaultArr){
			targetList.add(defaultItem);
		}
		for(String targetItem : targetArr){
			targetList.add(targetItem);
		}
		return targetList;
	}
	
	
	public Object queryData(String reportid){
		DvReportExportStatus dvReportExportStatus = reportExportStatusMapper.queryReportStatusByReportId(reportid);
		SingleProductReportExportVO spreVo = JSON.parseObject(dvReportExportStatus.getReportparam(), SingleProductReportExportVO.class);
		return queryData(spreVo);
	}
	public Object queryData(SingleProductReportExportVO spreVo){
		if(spreVo.getOrdersource()==null||spreVo.getOrdersource().length<1){
			return ServerResponse.createByErrorMessage("平台为空,请修改报表！");
		}
		SingleProductReportExportPO sprePo= new SingleProductReportExportPO();
		Map<String,Object> resultMap = Maps.newHashMap();
		String[] targetArr = spreVo.getTarget();
		List<String> targetList = getTargetList(spreVo.getSummaryCycle(), targetArr);
		Long start = System.currentTimeMillis();
		List<DvExcelFieldDefinitionEntity>  reportFieldDefinition= reportCommonService.getExcelFieldDefinitionList(reporttype);
		//装载表格数据
		List<List<String>> tableList = Lists.newArrayList();

		List<String> titleList = Lists.newArrayList();
		for(String item : targetList){
			for(DvExcelFieldDefinitionEntity definition : reportFieldDefinition){
				String name = definition.getEntityName();
				if(item.equals(name)){
					//添加分组
					addGorups(sprePo,name);
					//添加分类
					addCategory(sprePo,definition.getCategoryId());
					titleList.add(definition.getTitle());
				}
			}
		}
		tableList.add(titleList);
		System.out.println("1."+(System.currentTimeMillis()-start)/1000);
		
		List<String> searchItemList = Lists.newArrayList();
		//查找附件内容作为搜索条件
		if("wareCode".equals(spreVo.getSearchName())){
			if(StringUtils.isNotBlank(spreVo.getUploadFileId())){
				int partSize=1000;
				String fileName = reportImportStatusMapper.queryReportStatusByUUID(spreVo.getUploadFileId()).getFileName();
				File uploadFile = new File(uploadPath+fileName);
				FileInputStream readStream = null;
				try {
					readStream = new FileInputStream(uploadFile);
					List<List<Object>> datas =POIExcelUtils.readExcel(readStream, 0);
					for(int i=0,len=datas.size();i<len;i++){
						if(i>0&&datas.get(i).get(0)!=null){
							searchItemList.add(datas.get(i).get(0).toString());
						}
					}
					dvReportSearchTmpMapper.deleteDvReportSearchTmp(spreVo.getUserid());
					if(searchItemList.size()>partSize){
						int part = searchItemList.size()/partSize;
						for(int i=0;i<part;i++){
							List<String> tmpList  = searchItemList.subList(0, partSize);
							dvReportSearchTmpMapper.insertDvReportSearchTmpByBatch(spreVo.getUserid(), tmpList);
							searchItemList.subList(0, partSize).clear();
						}
					}
					if(searchItemList.size()>0){
						dvReportSearchTmpMapper.insertDvReportSearchTmpByBatch(spreVo.getUserid(), searchItemList);
					}
				} catch (FileNotFoundException e) {
					e.printStackTrace();
				}
				spreVo.setSearchValue(searchItemList.size()>0?searchItemList.toArray(new String[searchItemList.size()]):null);
			}else{
				spreVo.setSearchValue(null);
			}
		}else if("wareName".equals(spreVo.getSearchName())){
			if(spreVo.getSearchValue().length>0){
				if(StringUtils.isNotBlank(spreVo.getSearchValue()[0])){
					spreVo.setSearchValue(spreVo.getSearchValue());
				}
			}else{
				spreVo.setSearchValue(null);
			}
		}
		System.out.println("2."+(System.currentTimeMillis()-start)/1000);
		BeanUtils.copyProperties(spreVo, sprePo);
		//根据权限进行查询或者下载，单品分析页面要判断用户是否是属于商品经理订阅的报表，如果是对应的商品经理只能下载所管理的商品否则可以下载全部商品根据(0是1不是-1找不到角色，有问题可咨询庄曼娜李建华)
		int type = reportExportPermissionService.getManagerType(sprePo.getUserid(), reporttype);
		//商品经理过滤 有数据就去掉之前的逻辑否则不用。
		List<String> names = commonMapper.getNoFilterGoodsManager(sprePo.getUsername());
		if(names!=null && names.size()>0){
			type = 1;
		}
		System.out.println(sprePo);
		List<DwSingleProductEntity> list = singleProductReportExportMapper.querySingleProductInfo(sprePo,1,10,type);
		System.out.println("单品分析查询数据 list:"+list.size()+" type:"+type);
		JSONArray objectArr = JSON.parseArray(JSONObject.toJSONString(list));
		for(int i = 0,len = objectArr.size() ; i<len ; i++){
			JSONObject object = objectArr.getJSONObject(i);
			List<String> itemList = Lists.newArrayList();
			for(String item : targetList){
				itemList.add(object.getString(item)==null?"":object.getString(item));
			}
			tableList.add(itemList);
		}
		System.out.println("3."+(System.currentTimeMillis()-start)/1000);
		resultMap.put("tableData",tableList );
		resultMap.put("rownum",list.size()>0?list.get(0).getCountNum():0);
		return ServerResponse.createBySuccess(resultMap);
	}
	

	public Object addOrUpdateReport(SingleProductReportExportVO spreVo){
		String reportid = spreVo.getReportid();
		List<String> targetNameList = Lists.newArrayList();
		String[] targetArr = spreVo.getTarget();

		List<DvExcelFieldDefinitionEntity> excelFieldDefinitionList = reportCommonService.getExcelFieldDefinitionList(reporttype);
		for(String target : targetArr){
			for(DvExcelFieldDefinitionEntity dvExcelFieldDefinitionItem : excelFieldDefinitionList){
				String entityName = dvExcelFieldDefinitionItem.getEntityName();
				String targetName = dvExcelFieldDefinitionItem.getTitle();
					if(target.equals(entityName)){
						targetNameList.add(targetName);
					}
			}
		}
		int type = reportExportPermissionService.getManagerType(spreVo.getUserid(), reporttype);
		//商品经理过滤 有数据就去掉之前的逻辑否则不用。
		List<String> names = commonMapper.getNoFilterGoodsManager(spreVo.getUsername());
		if(names!=null && names.size()>0){
			type = 1;
		}
		SingleProductReportManageVO singleProductReportManageVO = new SingleProductReportManageVO();
		singleProductReportManageVO.setReportid(reportid);
		singleProductReportManageVO.setReportName(spreVo.getReportName());
		singleProductReportManageVO.setQueryRange(spreVo.getQueryRange());
		//权限修改了平台ID,对应的平台名称也要变
		singleProductReportManageVO.setSourcename(reportCommonService.getOrderSourceName(spreVo.getOrdersource(), commonService.getOrderSource( type, spreVo.getUserid(),reporttype)));
		singleProductReportManageVO.setTargetName(targetNameList);
		singleProductReportManageVO.setSummaryCycle(SummaryCycleEnum.getSummaryCycleName(spreVo.getSummaryCycle()));
		singleProductReportManageVO.setUpdate(spreVo.getUpdate());
		singleProductReportManageVO.setSaveTime(DvDateUtils.format(new Date(),"yyyy-MM-dd HH:mm:ss"));
		//添加附件名字
		if(StringUtils.isNotBlank(spreVo.getUploadFileId())){
			String uploadFileName = reportImportStatusMapper.queryReportStatusByUUID(spreVo.getUploadFileId()).getReportName();
			spreVo.setUploadFileName(uploadFileName);
			singleProductReportManageVO.setUploadFileName(spreVo.getUploadFileName());
		}
		if("wareName".equals(spreVo.getSearchName())){
			String[] searchArr = spreVo.getSearchValue();
			if(searchArr!=null&&searchArr.length>0){
				singleProductReportManageVO.setSearchValue(spreVo.getSearchValue()[0]);
			}
		}
		if(StringUtils.isNotBlank(reportid)){
			DvReportExportStatus dvReportExportStatus = new DvReportExportStatus();
			dvReportExportStatus.setReportid(reportid);
			dvReportExportStatus.setReportName(spreVo.getReportName());
			dvReportExportStatus.setReportparam(JSON.toJSONString(spreVo));
			dvReportExportStatus.setReportManageParam(JSON.toJSONString(singleProductReportManageVO));
			if(reportExportStatusMapper.updateReportStatus(dvReportExportStatus)>0){
				return ServerResponse.createBySuccessMessage("修改报表成功!");
			}else{
				return ServerResponse.createBySuccessMessage("修改报表失败!");
			}
		}else{
			//加入报表前需要根据用户ID，报表名去判断是否有重名的报表
			if(reportExportStatusMapper.queryReport(spreVo.getUserid(), spreVo.getReportName())>0){
				return ServerResponse.createByErrorMessage("已存在相同名称的报表，请重新命名!");
			}else{
				reportid = reporttype+String.valueOf(System.currentTimeMillis())+String.valueOf((int)((Math.random()*9+1)*100000));
				spreVo.setReportid(reportid);
				singleProductReportManageVO.setReportid(reportid);
				DvReportExportStatus dvReportExportStatus = new DvReportExportStatus();
				BeanUtils.copyProperties(spreVo, dvReportExportStatus);
				dvReportExportStatus.setCreatetime(new Date());
				dvReportExportStatus.setReportparam(JSON.toJSONString(spreVo));
				dvReportExportStatus.setReportManageParam(JSON.toJSONString(singleProductReportManageVO));
				dvReportExportStatus.setReporttype(reporttype);
				dvReportExportStatus.setFileName(spreVo.getUploadFileId()+spreVo.getUploadFileName());
				if(reportExportStatusMapper.insertReportStatus(dvReportExportStatus)>0){
					return ServerResponse.createBySuccessMessage("添加报表成功!");
				}else{
					return ServerResponse.createByErrorMessage("添加报表失败!");
				}
			}
		}
	}
	

	public Object download(SingleProductReportExportVO spreVo,HttpServletRequest request){
		context.initDBExcelDefinitionReader("export");
		List<DvExcelFieldDefinitionEntity>  reportFieldDefinition= reportCommonService.getExcelFieldDefinitionList(reporttype);
		SingleProductReportExportPO sprePo= new SingleProductReportExportPO();
		String[] targetArr = spreVo.getTarget();
		List<String> targetList = getTargetList(spreVo.getSummaryCycle(), targetArr);
		for(String item : targetList){
			for(DvExcelFieldDefinitionEntity definition : reportFieldDefinition){
				String name = definition.getEntityName();
				if(item.equals(name)){
					//添加分组
					addGorups(sprePo,name);
					//添加分类
					addCategory(sprePo,definition.getCategoryId());
				}
			}
		}
		List<String> searchItemList = Lists.newArrayList();
		//查找附件内容作为搜索条件
		if("wareCode".equals(spreVo.getSearchName())){
			if(StringUtils.isNotBlank(spreVo.getUploadFileId())){
				int partSize=1000;
				String fileName = reportImportStatusMapper.queryReportStatusByUUID(spreVo.getUploadFileId()).getFileName();
				File uploadFile = new File(uploadPath+fileName);
				FileInputStream readStream = null;
				try {
					readStream = new FileInputStream(uploadFile);
					List<List<Object>> datas =POIExcelUtils.readExcel(readStream, 0);
					for(int i=0,len=datas.size();i<len;i++){
						if(i>0&&datas.get(i).get(0)!=null){
							searchItemList.add(datas.get(i).get(0).toString());
						}
					}
					dvReportSearchTmpMapper.deleteDvReportSearchTmp(spreVo.getUserid());
					if(searchItemList.size()>partSize){
						int part = searchItemList.size()/partSize;
						for(int i=0;i<part;i++){
							List<String> tmpList  = searchItemList.subList(0, partSize);
							dvReportSearchTmpMapper.insertDvReportSearchTmpByBatch(spreVo.getUserid(), tmpList);
							searchItemList.subList(0, partSize).clear();
						}
					}
					if(searchItemList.size()>0){
						dvReportSearchTmpMapper.insertDvReportSearchTmpByBatch(spreVo.getUserid(), searchItemList);
					}
				} catch (FileNotFoundException e) {
					e.printStackTrace();
				}
				spreVo.setSearchValue(searchItemList.size()>0?searchItemList.toArray(new String[searchItemList.size()]):null);
			}else{
				spreVo.setSearchValue(null);
			}
		}else if("wareName".equals(spreVo.getSearchName())){
			if(spreVo.getSearchValue().length>0){
				if(StringUtils.isNotBlank(spreVo.getSearchValue()[0])){
					spreVo.setSearchValue(spreVo.getSearchValue());
				}
			}else{
				spreVo.setSearchValue(null);
			}
		}
		BeanUtils.copyProperties(spreVo, sprePo);
		
		//用户ID，UUID组成下载ID
		String downloadId = spreVo.getUserid()+UUID.randomUUID().toString().replaceAll("-", "");
		String downloadReportName = spreVo.getReportName();
		String fileName =downloadId+downloadReportName+".xlsx";
		int type = reportExportPermissionService.getManagerType(sprePo.getUserid(), reporttype);
		//商品经理过滤 有数据就去掉之前的逻辑否则不用。
		List<String> names = commonMapper.getNoFilterGoodsManager(sprePo.getUsername());
		if(names!=null && names.size()>0){
			type = 1;
		}
		int rownum = singleProductReportExportMapper.querySingleProductInfoCount(sprePo,type);
		DvReportDownloadStatusEntity dvReportDownloadStatusEntity = new DvReportDownloadStatusEntity();
		dvReportDownloadStatusEntity.setDownloadId(downloadId);
		dvReportDownloadStatusEntity.setFileName(fileName);
		dvReportDownloadStatusEntity.setReportName(downloadReportName);
		dvReportDownloadStatusEntity.setReportType(reporttype);
		dvReportDownloadStatusEntity.setUserid(spreVo.getUserid());
		dvReportDownloadStatusEntity.setUsername(spreVo.getUsername());
		dvReportDownloadStatusEntity.setUserrealname(spreVo.getUserrealname());
		dvReportDownloadStatusEntity.setTargetName(JSON.toJSONString(reportCommonService.getTargetNameList(targetArr, reporttype)));
		dvReportDownloadStatusEntity.setIp(DvUtils.getIp(request));
		
		if(reportDownloadStatusMapper.insertReport(dvReportDownloadStatusEntity)>0){
			DownloadTask downloadTask = new DownloadTask(fileName,targetList,rownum,sprePo,dvReportDownloadStatusEntity,type);
			new Thread(downloadTask).start();  
			return ServerResponse.createBySuccessMessage("加入下载列表成功！");
		}else{
			return ServerResponse.createByErrorMessage("加入下载列表失败！");
		}
	}
	public Object addDownloadTask(String reportid,HttpServletRequest request){
		DvReportExportStatus dvReportExportStatus = reportExportStatusMapper.queryReportStatusByReportId(reportid);
		SingleProductReportExportVO spreVo = JSON.parseObject(dvReportExportStatus.getReportparam(), SingleProductReportExportVO.class);
		return download(spreVo,request);
	}
	public Object addDownloadTask(SingleProductReportExportVO spreVo,HttpServletRequest request){
		if(reportDownloadStatusMapper.queryReportByName(spreVo.getUserid(), spreVo.getReportName())>0){
			return ServerResponse.createByErrorMessage("已存在相同名称的报表，请重新命名!");
		}else{
			return download(spreVo,request);
		}
	}
	
	class DownloadTask implements Runnable{
		public  boolean flag = true;
		private String fileName;
		private Integer rownum;
		private List<String> targetList;
		private SingleProductReportExportPO sprePo;
		private DvReportDownloadStatusEntity dvReportDownloadStatusEntity;
		private int type;
		public DownloadTask(String fileName,List<String> targetList,int rownum,SingleProductReportExportPO sprePo,DvReportDownloadStatusEntity dvReportDownloadStatusEntity,int type){
			this.fileName = fileName;
			this.rownum = rownum;
			this.targetList = targetList;
			this.sprePo = sprePo;
			this.dvReportDownloadStatusEntity = dvReportDownloadStatusEntity;
			this.type = type;
		}
		public void stopThread(){
			flag = false;
		}
		@Override
		public void run() {
			while (flag){
				OutputStream ops = null;
				ExcelExportResult exportResult = null;
				try {
					ops = new FileOutputStream(downloadPath+fileName);
					System.out.println("targetList:"+targetList.size());
					exportResult = context.createEmptyExcelForPart(reporttype,DwSingleProductEntity.class,targetList);
					int pageSize = 40000;
					int totalPage = (int)Math.ceil(rownum/pageSize);
					totalPage += rownum%pageSize>0?1:0; 
					for(int i=1;i<=totalPage;i++){
						exportResult.append(singleProductReportExportMapper.querySingleProductInfo(sprePo,i,pageSize,type));
					}
				Workbook workbook = exportResult.build();
				workbook.write(ops);
				ops.close();
				workbook.close();
				dvReportDownloadStatusEntity.setEndDate(new Date());
				dvReportDownloadStatusEntity.setTimeConsume(Math.round(dvReportDownloadStatusEntity.getEndDate().getTime()-dvReportDownloadStatusEntity.getBeginDate().getTime())/1000);
				dvReportDownloadStatusEntity.setDownloadFlag(1);
				reportDownloadStatusMapper.updateReportById(dvReportDownloadStatusEntity);
				this.stopThread();
				} catch (Exception e) {
					System.out.println("SingleProductReprot awaitTermination interrupted: " + e);  
					this.stopThread();
				}
			}
		}
	}
	
	
	
	//更新报表，每天，每周一，每月一号
	public void updateReport(){
		List<DvReportExportStatus> dvReportExportStatusList = reportExportStatusMapper.queryMyReportByReportType(reporttype);
		for(DvReportExportStatus dvReportExportStatusItem : dvReportExportStatusList){
			SingleProductReportExportVO spreVo = JSON.parseObject(dvReportExportStatusItem.getReportparam(), SingleProductReportExportVO.class);
			if("subscription".equals(spreVo.getFetchType())){
				String summaryCycle = spreVo.getSummaryCycle();
				String beginDate = spreVo.getBeginDate();
				String endDate = spreVo.getEndDate();
				try {
					int daysBetween = DvDateUtils.daysBetween(endDate, beginDate)+1;
					Date today = new Date();
					Calendar calendar = Calendar.getInstance();
					calendar.setTime(today);
					int week = calendar.get(Calendar.DAY_OF_WEEK)-1;
					String day = DvDateUtils.format(today, "dd");
					if("naturalDay".equals(summaryCycle)
							||"custom".equals(summaryCycle)
							||("naturalWeek".equals(summaryCycle)&&week==1)
							||("naturalMonth".equals(summaryCycle)&&"01".equals(day))){
						spreVo.setBeginDate(DvDateUtils.format(DvDateUtils.getOffsetDay(today, -daysBetween), "yyyy-MM-dd"));
						spreVo.setEndDate(DvDateUtils.format(DvDateUtils.getOffsetDay(today, -1), "yyyy-MM-dd"));
						addOrUpdateReport(spreVo);
					}
				} catch (ParseException e) {
					e.printStackTrace();
				}
			}
		}
	}
}
